//package com.guijq.codesegment.util;
//
//
//import javax.validation.ConstraintViolation;
//import javax.validation.Validation;
//import javax.validation.Validator;
//
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.FileNotFoundException;
//import java.io.FileOutputStream;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.math.BigDecimal;
//import java.text.MessageFormat;
//import java.text.SimpleDateFormat;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Date;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//
//import com.guijq.codesegment.exception.BaseException;
//import org.apache.poi.hssf.usermodel.HSSFWorkbook;
//import org.apache.poi.ss.usermodel.Cell;
//import org.apache.poi.ss.usermodel.DateUtil;
//import org.apache.poi.ss.usermodel.Row;
//import org.apache.poi.ss.usermodel.Sheet;
//import org.apache.poi.ss.usermodel.Workbook;
//import org.apache.poi.xssf.usermodel.XSSFWorkbook;
//import org.springframework.core.io.ClassPathResource;
//import org.springframework.util.CollectionUtils;
//import org.springframework.util.StringUtils;
//
//
//
//
//public class ExcelUtils {
//
//    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//    private static int DEFAULT_MAX_RECORDS = 100000;
//    /**
//     * suffix of excel 2003
//     */
//    public static final String OFFICE_EXCEL_V2003_SUFFIX = "xls";
//    /**
//     * suffix of excel 2007
//     */
//    public static final String OFFICE_EXCEL_V2007_V2010_SUFFIX = "xlsx";
//
//    public static final String TEMPLATE_PATH_NAME = "exportTemplate/template.xlsx";
//
//
//    public static String getExcelSuffix(String fileName) {
//        String suffiex = getSuffix(fileName);
//        if (OFFICE_EXCEL_V2003_SUFFIX.equals(suffiex) || OFFICE_EXCEL_V2007_V2010_SUFFIX.equals(suffiex)) {
//            return suffiex;
//        } else {
//            throw new BaseException(MessageFormat.format("文件{0}拓展名不合规，支持格式：xls，xlsx。", fileName));
//        }
//    }
//
//    /**
//     * 导出单个sheet excel
//     *
//     * @param sheetName
//     * @param entityList
//     * @param srcClazz
//     * @param path
//     * @param <T>
//     * @return
//     */
//    public static <T> File exportSingleSheetExcel(String sheetName, List<T> entityList, Class<T> srcClazz, String path) {
//        try {
//            File excelFile = new File(path);
//            OutputStream out = new FileOutputStream(excelFile);
//            String[] filedNames = FieldTool.getFieldNames(srcClazz);
//            exportExcel(sheetName, filedNames, entityList, out);
//            //添加导出规格说明表
//            exportSpecifications(excelFile);
//            return excelFile;
//        } catch (Exception ex) {
//            throw new BaseException("导出excel表错误");
//        }
//    }
//
//    /**
//     * 将默认规格说明跟随导出
//     *
//     * @param targetFile
//     */
//    public static void exportSpecifications(File targetFile) {
//        Workbook workbook = null;
//        Workbook templateWorkbook = null;
//        OutputStream ot = null;
//        try {
//            if (null != targetFile) {
//                String suffix = getExcelSuffix(targetFile.getName());
//                workbook = createWorkBook(targetFile, suffix);
//                //获取规格说明
//                InputStream is = getTemplateExcelInputStream(TEMPLATE_PATH_NAME);
//                templateWorkbook = createWorkBook(is, OFFICE_EXCEL_V2007_V2010_SUFFIX);
//                String tempSheetName = getFileName(targetFile.getName());
//                Sheet templateSheet = templateWorkbook.getSheet(tempSheetName);
//                if (null == templateSheet) {
//                    throw new BaseException(tempSheetName + "导出模板表不存在");
//                }
//                Sheet newSheet = workbook.createSheet(tempSheetName + "导出规格说明");
//                ExcelOperationUtils.copySheet(templateSheet, newSheet, ExcelOperationUtils.copyCellStyle(templateWorkbook, workbook));
//                ot = new FileOutputStream(targetFile);
//                workbook.write(ot);
//            } else {
//                throw new BaseException();
//            }
//        } catch (BaseException ex) {
//            throw ex;
//        } catch (Exception e) {
//            throw new BaseException(e.getMessage());
//        } finally {
//            if (null != workbook) {
//                try {
//                    workbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            if (null != ot) {
//                try {
//                    ot.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            if (null != templateWorkbook) {
//                try {
//                    templateWorkbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return;
//    }
//
//
//    public static InputStream getTemplateExcelInputStream(String pathName) {
//        ClassPathResource classPathResource = new ClassPathResource(pathName);
//        InputStream inputStream = null;
//        try {
//            inputStream = classPathResource.getInputStream();
//        }
//        catch (IOException e) {
//            throw new BaseException("读入模板文件错误");
//        }
//        return inputStream;
//
//    }
//
//
//    /**
//     * 这是一个通用的方法，利用了JAVA的反射机制，可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
//     *
//     * @param title      表格标题名
//     * @param headers    表格属性列名数组
//     * @param entityList 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的
//     *                   javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
//     * @param out        与输出设备关联的流对象，可以将EXCEL文档导出到本地文件或者网络中
//     */
//    @SuppressWarnings("unchecked")
//    public static <T> void exportExcel(String title, String[] headers,
//                                       List<T> entityList, OutputStream out) {
//        // 声明一个工作薄
//        Workbook workbook = new XSSFWorkbook();
//        // 生成一个表格
//        Sheet sheet = workbook.createSheet(title);
//
//        try {
//            // 产生表格标题行
//            Row headRow = sheet.createRow(0);
//            for (short i = 0; i < headers.length; i++) {
//                Cell cell = headRow.createCell(i);
//                cell.setCellValue(headers[i]);
//            }
//            if (!CollectionUtils.isEmpty(entityList)) {
//                for (int j = 0; j < entityList.size(); j++) {
//                    T t = entityList.get(j);
//                    Row row = sheet.createRow(j + 1);
//                    for (int i = 0; i < headers.length; i++) {
//                        Cell cell = row.createCell(i);
//                        Object value = FieldTool.getFieldValueByName(headers[i], t);
//                        if (null == value) {
//                            // do nothing
//                        } else if (value instanceof Boolean) {
//                            cell.setCellValue((Boolean) value);
//                        } else if (value instanceof Date) {
//                            cell.setCellValue((Date) value);
//                        } else if (value instanceof String) {
//                            cell.setCellValue(value.toString());
//                        } else if (value instanceof Integer) {
//                            cell.setCellValue((Integer) value);
//                        } else if (value instanceof Double) {
//                            cell.setCellValue((Double) value);
//                        } else if (value instanceof BigDecimal) {
//                            cell.setCellValue(((BigDecimal) value).doubleValue());
//                        } else {
//                            throw new BaseException("导出对象的字段类型仅支持: Boolean, Date, String, Integer");
//                        }
//                    }
//                }
//            }
//            workbook.write(out);
//        } catch (BaseException ex) {
//            throw ex;
//        } catch (Exception e) {
//            throw new BaseException("导出excel失败");
//        } finally {
//            if (out != null) {
//                try {
//                    out.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//            if (null != workbook) {
//                try {
//                    workbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    /*===========================================================================================================================*/
//
//    private static Workbook createWorkBook(InputStream is, String suffix) {
//        Workbook workbook = null;
//        try {
//            if (OFFICE_EXCEL_V2003_SUFFIX.equals(suffix)) {
//                workbook = new HSSFWorkbook(is);
//            } else if (OFFICE_EXCEL_V2007_V2010_SUFFIX.equals(suffix)) {
//                workbook = new XSSFWorkbook(is);
//            } else {
//                throw new IllegalArgumentException("文件流不是excel文件");
//            }
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            if (null != is) {
//                try {
//                    is.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return workbook;
//    }
//
//    private static Workbook createWorkBook(File file, String suffix) {
//        Workbook workbook = null;
//        InputStream is = null;
//        try {
//            is = new FileInputStream(file);
//            if (OFFICE_EXCEL_V2003_SUFFIX.equals(suffix)) {
//                workbook = new HSSFWorkbook(is);
//            } else if (OFFICE_EXCEL_V2007_V2010_SUFFIX.equals(suffix)) {
//                workbook = new XSSFWorkbook(is);
//            } else {
//                throw new IllegalArgumentException(MessageFormat.format("文件{0}不是excel文件", file.getName()));
//            }
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            if (null != is) {
//                try {
//                    is.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return workbook;
//    }
//
//
//    public static <T> T readRow(Row row, Class<T> dstClazz, Row titleRow) {
//        // 获得行对象
//        if (row == null) {
//            throw new BaseException("行数据为空", ErrorType.ERROR_EXCEL_NULL_ROW.getIndex());
//        }
//        T dest = null;
//        // 实例化该泛型类的对象一个对象
//        try {
//            dest = dstClazz.newInstance();
//        } catch (Exception e1) {
//            e1.printStackTrace();
//        }
//
//        // 获得本行中各单元格中的数据
//        for (int columnIndex = 0; columnIndex < titleRow.getLastCellNum() + 1; columnIndex++) {
//            Cell fieldCell = titleRow.getCell(columnIndex);
//            if (null == fieldCell) {
//                continue;
//            }
//            //属性名
//            String fieldName = fieldCell.toString();
//            Cell cell = row.getCell(columnIndex);
//            try {
//                if (null != cell) {
//                    FieldTool.setFieldValueByName(fieldName, dest, getValue(cell));
//                }
//            } catch (Exception ex) {
//                throw new BaseException(MessageFormat.format("第{0}列数据转换时出错：" + cell.getStringCellValue(), columnIndex + 1), ErrorType.ERROR_EXCEL_CELL_ERROR.getIndex());
//            }
//        }
//        return dest;
//    }
//
//    private static void checkTitleRow(Row titleRow, Class dstClazz) {
//        String[] fieldNames = FieldTool.getFieldNames(dstClazz);
//
//        for (int columnIndex = 0; columnIndex < titleRow.getLastCellNum() + 1; columnIndex++) {
//            Cell cell = titleRow.getCell(columnIndex);
//            List<String> fieldNameAry = Arrays.asList(fieldNames);
//            if (null != cell) {
//                String fieldName = cell.getStringCellValue();
//                if (!fieldNameAry.contains(fieldName)) {
//                    throw new BaseException(MessageFormat.format("表头字段{0}不符合模板要求，请确认模板是否正确", fieldName), ErrorType.ERROR_EXCEL_TEMPLATE.getIndex());
//                }
//            } else if (null == cell && columnIndex == titleRow.getLastCellNum()) {
//                //do nothing
//            } else {
//                throw new BaseException(MessageFormat.format("第{0}列的表头字段为空", columnIndex + 1), ErrorType.ERROR_EXCEL_TEMPLATE.getIndex());
//            }
//        }
//    }
//
//    /**
//     *
//     * @param sheet
//     * @param dstClazz
//     * @param maxRecords
//     * @param checker 个性化校验器, 如果传null 则没有校验
//     * @param <T>
//     * @return
//     */
//    public static <T> List<T> readSheet(Sheet sheet, Class<T> dstClazz, Integer maxRecords, ICheckParam<T> checker) {
//        //读取表头
//        List<T> result = new ArrayList();
//        Row titleRow = sheet.getRow(0);
//        // 逐行读取数据 从rowIndex = 1 (第二行)开始  忽略表头
//        //校验模板是否正确，
//        if (titleRow == null) {
//            throw new BaseException("excel表列名不存在，请检查excel模板是否正确");
//        }
//        checkTitleRow(titleRow, dstClazz);
//        if (null == maxRecords) {
//            maxRecords = DEFAULT_MAX_RECORDS;
//        }
//        if (sheet.getLastRowNum() > maxRecords.intValue()) {
//            throw new BaseException("文件记录数条数限制为：" + maxRecords, ErrorType.ERROR_EXCEL_TEMPLATE.getIndex());
//        }
//        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
//        for (int rowIndex = 1; rowIndex < sheet.getLastRowNum() + 1; rowIndex++) {
//            try {
//                Row row = sheet.getRow(rowIndex);
//                if (null != row) {
//                    T t = readRow(row, dstClazz, titleRow);
//                    Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
//                    if (!CollectionUtils.isEmpty(constraintViolations)) {
//                        for (ConstraintViolation constraintViolation : constraintViolations) {
//                            throw new BaseException(constraintViolation.getMessage(), ErrorType.ERROR_EXCEL_CELL_ERROR.getIndex());
//                        }
//                    }
//                    //个性化校验
//                    if (null != checker) {
//                        checker.check(t);
//                    }
//                    result.add(t);
//                }
//            } catch (BaseException ex) {
//                throw new BaseException(MessageFormat.format("第{0}行，", rowIndex + 1) + ex.getMessage(), ErrorType.ERROR_EXCEL_CELL_ERROR.getIndex());
//            }
//        }
//        return result;
//    }
//
//
//    public static <T> List<T> readSheetByName(File file, Class<T> detClazz, Integer maxRecords, String sheetName, ICheckParam<T> checker) {
//        Workbook workbook = null;
//        try {
//            String suffiex = getExcelSuffix(file.getName());
//            workbook = createWorkBook(file, suffiex);
//            // Read the Sheet
//            Sheet sheet = workbook.getSheet(sheetName);
//            if (null == sheet) {
//                throw new BaseException(MessageFormat.format("文件中不存在sheet名:{0},请确认excel模板是否正确", sheetName));
//            }
//            List<T> results = readSheet(sheet, detClazz, maxRecords, checker);
//            return results;
//        } finally {
//            if (null != workbook) {
//                try {
//                    workbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//    }
//
//    public static <T> List<T> readSheetByName(File file, Class<T> detClazz, Integer maxRecords, String sheetName) {
//        Workbook workbook = null;
//        try {
//            String suffiex = getExcelSuffix(file.getName());
//            workbook = createWorkBook(file, suffiex);
//            // Read the Sheet
//            Sheet sheet = workbook.getSheet(sheetName);
//            if (null == sheet) {
//                throw new BaseException(MessageFormat.format("文件中不存在sheet名:{0},请确认excel模板是否正确", sheetName));
//            }
//            List<T> results = readSheet(sheet, detClazz, maxRecords, null);
//            return results;
//        } finally {
//            if (null != workbook) {
//                try {
//                    workbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//
//    }
//
//    /**
//     * 读取单个sheet excel表
//     *
//     * @param path
//     * @param detClazz
//     * @param <T>
//     * @return
//     * @throws IOException
//     */
//    public static <T> List<T> readSheetByName(String path, Class<T> detClazz, Integer maxRecords, String sheetName, ICheckParam<T> checker) {
//        File file = new File(path);
//        return readSheetByName(file, detClazz, maxRecords, sheetName, checker);
//    }
//
//    /**
//     * 读取多sheet excel表
//     *
//     * @param file the Excel file
//     * @return a list that contains Students from Excel.
//     * @throws IOException
//     */
//
//    public static Map<Class, List> readExcel(File file, List<Class> clazzList) {
//        String suffix = getExcelSuffix(file.getName());
//        Workbook workbook = null;
//        try {
//            workbook = createWorkBook(file, suffix);
//            // Read the Sheet
//            Map<Class, List> result = new HashMap();
//            for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
//                Sheet sheet = workbook.getSheetAt(numSheet);
//                List entityList = readSheet(sheet, clazzList.get(numSheet), null, null);
//                result.put(clazzList.get(numSheet), entityList);
//            }
//            return result;
//        } finally {
//            if (null != workbook) {
//                try {
//                    workbook.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//    }
//
//    /**
//     * 读取多sheet excel表
//     *
//     * @param path the Excel file
//     * @return a list that contains Students from Excel.
//     * @throws IOException
//     */
//
//    public static Map<Class, List> readExcel(String path, List<Class> clazzList) throws IOException, IllegalArgumentException, IllegalAccessException, InstantiationException {
//        File file = new File(path);
//        return readExcel(file, clazzList);
//    }
//
//
//    @SuppressWarnings("static-access")
//    public static Object getValue(Cell cell) {
//        if (null == cell) {
//            return null;
//        }
//        switch (cell.getCellType()) {
//            case STRING:
//                String newValue = cell.getStringCellValue().trim();
//                if (StringUtils.isEmpty(newValue)) {
//                    return null;
//                } else {
//                    return newValue;
//                }
//            case BOOLEAN:
//                return cell.getBooleanCellValue();
//            case NUMERIC:
//                if (DateUtil.isCellDateFormatted(cell)) {
//                    return sdf.format(cell.getDateCellValue());
//                }
//                return cell.getNumericCellValue();
//            case FORMULA:
//            case ERROR:
//            case _NONE:
//                throw new BaseException("类型不支持", ErrorType.ERROR_EXCEL_CELL_ERROR.getIndex());
//            case BLANK:
//                return null;
//            default:
//                return cell.getStringCellValue();
//        }
//    }
//
//    public static String getSuffix(String path) {
//        return StringUtils.getFilenameExtension(path);
//    }
//
//    public static String getFileName(String fileName) {
//        if (!StringUtils.isEmpty(fileName)) {
//            return fileName.substring(0, fileName.lastIndexOf("."));
//        }
//        return null;
//    }
//
//}